home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: MegaDisc / MegaDisc 45 (1996-03)(MegaDisc Digital Publishing)(AU)(Disk 1 of 2)[WB].zip / MegaDisc 45 (1996-03)(MegaDisc Digital Publishing)(AU)(Disk 1 of 2)[WB].adf / arexx / Circular / Circular.rexx < prev    next >
OS/2 REXX Batch file  |  1995-08-18  |  18KB  |  454 lines

  1.  
  2.     /*                 Circles and Things                  */
  3.     /*                  by  John Collett                   */
  4.  
  5.     signal on syntax ; signal on error
  6.     
  7.     /* Handy escape if things go wrong */
  8.     if arg() ~= 0 then signal Finish
  9.  
  10.     /* Open libs */
  11.      l.1 = 'rexxsupport.library' ; l.2 = 'rexxarplib.library' 
  12.      l.3 = 'rexxmathlib.library'
  13.      if ~exists('LIBS:' || l.3) then do
  14.        say "Sorry. " || l.3 || " needed." ; exit ; end  
  15.      do i = 1 to 3 ; if ~show('L',l.i) then check = addlib(l.i,0,-30,0)
  16.      end
  17.     
  18.     /* Open screen */
  19.     call OpenScreen(0,4,HIRES,"",S,"121213102",640,255) 
  20.     
  21.     /* Prep window, etc. */
  22.     address AREXX '"call CreateHost(W, PORT, S)"'        
  23.     if ~show('Ports',W) then address command 'WaitForPort W' 
  24.     flags = 'BORDERLESS + WINDOWCLOSE + WINDOWSIZE + WINDOWDRAG'
  25.     idcmp = 'CLOSEWINDOW+GADGETUP+VANILLAKEY'
  26.     call OpenWindow(W,0,0,640,255,idcmp,flags)   
  27.     call openport(PORT) ; call ActivateWindow(W)
  28.     call rect(20,1,640,8,0) ; call palet()
  29.     call ModifyHost(W,'VANILLAKEY','%l %c %x %y')
  30.     call SetReqColor(W,BOXPEN,2)
  31.     call AddGadget(W,570,230,1,"Next",'%l %d')
  32.     call AddGadget(W,570,244,2,"List",'%l %d')
  33.     PI = 3.14159265359 ; twoPi = PI*2
  34.     scrno = 1 ; call Screen1()
  35.      
  36.             /* Loop here until Close */
  37.     do forever                               
  38.       call waitpkt(PORT) ; pkt = getpkt(PORT)                       
  39.       if pkt ~== NULL() then do
  40.         received = getarg(pkt) ; ack = reply(pkt, 0)
  41.         parse var received arg1 arg2 arg3
  42.         select
  43.           when arg1 = 'VANILLAKEY' then do
  44.             a = arg2-48 ; if (a=49) | (a=17) then a = 10
  45.             if a>0 & a<11 then do
  46.               scrno = a ; call GoScreen() ; end
  47.             end
  48.           when arg1 = 'GADGETUP' then do
  49.             if arg2 = 1 then do
  50.               if scrno < 10 then scrno = scrno + 1 ; else scrno = 1
  51.               call GoScreen() 
  52.               end
  53.             else call ShowList()
  54.             end
  55.           when arg1 = 'CLOSEWINDOW' then signal 'Finish'
  56.           otherwise
  57.           end  /* of 'select'         */
  58.         end    /* of 'if ... then do' */
  59.       end      /* of 'do forever'     */
  60.   
  61.     Finish:
  62.       call CloseWindow(W) 
  63.       r = CloseScreen(S) 
  64.       exit       
  65.  
  66.     /* Error trapping */    
  67.     syntax: say 'Syntax : ' errortext(rc) '. Line 'sigl ; signal 'Finish'
  68.     error: say "Error " rc sigl ; signal 'Finish'
  69.     
  70.     /* -----  User-defined functions from here on down  ----- */
  71.     GoScreen:
  72.      call rect(0,10,640,255,0) ; call RefreshGadgets(W)
  73.      select
  74.        when scrno = 1 then call Screen1()
  75.        when scrno = 2 then call Screen2()
  76.        when scrno = 3 then call Screen3()
  77.        when scrno = 4 then call Screen4()
  78.        when scrno = 5 then call Screen5()
  79.        when scrno = 6 then call Screen6()
  80.        when scrno = 7 then call Screen7()
  81.        when scrno = 8 then call Screen8()
  82.        when scrno = 9 then call Screen9()
  83.        when scrno = 10 then call Screen10()
  84.        otherwise
  85.        end
  86.       return
  87.     
  88.     ShowList: 
  89.      a = "You can go to the next screen by clicking the 'Next' gadget.",
  90.       "\After 10, you'll go back to 1. Use the 'Close' gadget to quit.",
  91.       "\If, instead of 'Next', you press a number key in the range",
  92.       "\1 - 9 (A for 10), you will go directly to that screen.",
  93.       "\Screen topics are : ",
  94.       "\\     1  Circles            6  Segments",
  95.       "\     2  Polygons           7  Cylinders",
  96.       "\     3  Arcs (1)           8  Globes", 
  97.       "\     4  Arcs (2)           9  Ellipticals",    
  98.       "\     5  Sectors            A (or a) Arguments"
  99.      r = Request(40,90,a,,"Okay",,S) ; call rect(20,1,640,8,0)
  100.      return
  101.       
  102.     pat:       
  103.       call APen(arg(4)) ; call Move(W,arg(1),arg(2)) ; call Text(W,arg(3))
  104.      return
  105.  
  106.     box:
  107.      call APen(arg(5)) ; call Move(W,arg(1),arg(2)) 
  108.      call Draw(W,arg(3),arg(2)) ; call Draw(W,arg(3),arg(4))
  109.      call Draw(W,arg(1),arg(4)) ; call Draw(W,arg(1),arg(2))
  110.      return
  111.  
  112.     rect:
  113.      call APen(arg(5)) ; call RectFill(W,arg(1),arg(2),arg(3),arg(4))
  114.     return
  115.                                 
  116.     APen: call SetAPen(W,arg(1)) ; return
  117.  
  118.     palet:
  119.       call SetRGB4(W,0,6,9,13)   ; call SetRGB4(W,1,0,0,6)
  120.       call SetRGB4(W,2,15,15,15) ; call SetRGB4(W,3,15,9,4)
  121.       call SetRGB4(W,4,15,0,0)   ; call SetRGB4(W,5,0,11,0)
  122.       call SetRGB4(W,6,0,7,15)   ; call SetRGB4(W,7,15,15,0)
  123.       do i = 8 to 15 ; j = i - 2 ; call SetRGB4(W,i,j,j,j) ; end
  124.       return   
  125.  
  126.          /*   ----------  Presentation screens   ----------   */
  127.     
  128.     Screen1:
  129.      a = "                     Circles and Things",
  130.      "\\       Circles and ellipses, with a variety of fillings, can",
  131.      "\       be produced easily and quickly by using the 'rexxarplib'",
  132.      "\       DrawEllipse, AreaEllipse, and AreaEnd functions."
  133.      call WindowText(W,a);call box(140,16,380,28,3);call box(138,15,382,29,1)  
  134.      do i = 1 to 4
  135.       call Apen(i) ; call DrawEllipse(W,100,110,90-i*10,45-i*5) ; end
  136.       call Apen(1) 
  137.      do i = 1 to 15
  138.       call AreaEllipse(W,200+20*i,110,20+i*4,30-i) 
  139.       call AreaEnd(W,2048*(i<8)+i)
  140.       end 
  141.      do i = 1 to 16
  142.       call AreaEllipse(W,36*i,170,20+i*2,10+i) ; call AreaEnd(W,2048+255+i)
  143.       end 
  144.      do i = 16 to 1 by -1
  145.       call AreaEllipse(W,30+36*i,210,52-i*2,26-i)
  146.       call AreaEnd(W,2048+512+i)
  147.       end
  148.      a="But when you want to move into the trickier area of *parts*",
  149.        "\of circles (arcs, chords, sectors, segments, etc.), you",
  150.        "\need to develop special functions.",
  151.        "\\That's what this program is all about."
  152.      r = Request(50,150,a,,"Okay",,S) ; call rect(20,1,640,8,0)
  153.      return
  154.     
  155.     Screen2:
  156.      a="  The key is to work with polygons rather than circles.  With 20",
  157.       "\  or more sides they look sufficiently like circles for most",
  158.       "\  purposes. Aim at a compromise between speed and smoothness :",
  159.       "\   - the more sides (up to 360?), the smoother the circle",
  160.       "\   - the fewer sides, the faster the execution, though it will",
  161.       "\     never be anything like as fast as the 'rexxarplib' functions.",
  162.       "\  Here are a few preliminary exercises."
  163.      call WindowText(W,a) 
  164.      call pat(38,160,"24-sided circle",1) ; call Polygon(90,120,60,30,24,1,1) 
  165.      call pat(136,238,"Double",1) ; call Polygon(160,200,60,30,10,14,0)
  166.      call Polygon(160,200,58,29,5,14,0) ; call pat(188,160,"With spokes",1)
  167.      call Spokes(230,120,60,30,24,7,1) ; call pat(270,238,"Rimless",1)
  168.      call Spokes(300,200,60,30,24,15,0) ; call pat(330,160,"Plain fill",1)
  169.      call Fill(370,120,60,30,12,1,2048+4)
  170.      call pat(394,238,"Patterned fill",1)
  171.      call Fill(440,200,60,30,8,1,2048+271)
  172.      call pat(460,160,"Dithered fill",1)
  173.      call Fill(510,120,60,30,6,1,2048+513)
  174.     
  175.      a="You may have noticed that my polygons are all constructed",
  176.       "\clock-wise from top-centre.  This took a bit of doing,",
  177.       "\but was worth it, because it makes it relatively easy to",
  178.       "\plan parts of circles, as shown on the following screens."
  179.      r = Request(50,150,a,,"Okay",,S) ; call rect(20,1,640,8,0)
  180.      return
  181.  
  182.     Screen3:
  183.      a = "                        Arcs",
  184.       "\\Details which have to be controlled are their centre, radius,",
  185.       "\colour, and span. The programming is a bit nasty if the span",
  186.       "\crosses the top centre, but it seems to work.",
  187.       "\\The examples below may not constitute a work of art, but the",
  188.       "\arcs produced are at least as I intend them to be."
  189.       call WindowText(W,a)    
  190.       call Arc(120,170,100,50,32,1,24,6);call Arc(130,170,90,45,32,1,25,5)
  191.       call Arc(140,170,80,40,32,1,24,4) ; call Arc(220,170,100,50,32,2,2,18)
  192.       call Arc(210,160,90,45,32,2,4,16) ; call Arc(200,150,80,40,32,2,6,14)
  193.       call Arc(160,144,100,50,32,4,10,22);call Arc(170,140,90,45,32,4,12,21)
  194.       call Arc(180,136,80,40,32,4,14,20) ;call Arc(450,170,80,40,32,1,20,4)
  195.       call Arc(475,183,88,44,32,1,22,2)
  196.       call APen(7) ; call Flood(W,1,400,150) ; call APen(1)
  197.      
  198.       a="Whereas a clockface has 12 points of reference, these arcs",
  199.        "\have 32 possible reference points, eight per quarter. So '8'",
  200.        "\points to 3 o'clock, '16' to 6 o'clock, '24' to 9 o'clock,",
  201.        "\and '32' (or '0') to 12 o'clock.",
  202.        "\This is as fine a scale as anyone is likely to need."
  203.        r = Request(50,150,a,,"Okay",,S) ; call rect(20,1,640,8,0)
  204.       return   
  205.       
  206.      Screen4:
  207.       a="This business of arcs is a bit complicated.",
  208.        "\An arc is just a piece of a circle. The arrangement in this",
  209.        "\program is that circles are really polygons. Most details for",
  210.        "\an arc are determined in the same way as for a complete polygon.",
  211.        "\But the *span* of an arc is always based on a 32-sided polygon.",
  212.        "\Advantages:    Easier to visualise and plan.",
  213.        "\               The arithmetic remained manageable (just).",
  214.        "\Disadvantage : The beginning and end of the arc MAY not coincide",
  215.        "\with the sides of the polygon, but I can't think of any",
  216.        "\application where this is likely to be a real inconvenience."
  217.       call WindowText(W,a)
  218.       call pat(40,200,"Four quarter-circle arcs fit reasonably",2)
  219.       call pat(40,209,"well into 32- and 16-sided polygons.",2)
  220.       call Spokes(150,160,60,30,32,15,0)
  221.       call Arc(150,160,60,30,32,4,0,8) ; call Arc(150,160,60,30,32,1,8,16)
  222.       call Arc(150,160,60,30,32,2,16,24);call Arc(150,160,60,30,32,3,24,32)
  223.      
  224.       call Spokes(300,160,60,30,16,15,0)
  225.       call Arc(300,160,60,30,16,4,0,8) ; call Arc(300,160,60,30,16,1,8,16)
  226.       call Arc(300,160,60,30,16,2,16,24);call Arc(300,160,60,30,16,3,24,32)
  227.      
  228.       call pat(400,200,"With 14 sides, the four",2)
  229.       call pat(400,209,"arcs just do not fit.",2)
  230.       call Spokes(450,160,60,30,14,15,0) 
  231.       call Arc(450,160,60,30,14,4,0,8) ; call Arc(450,160,60,30,14,1,8,16)
  232.       call Arc(450,160,60,30,14,2,16,24);call Arc(450,160,60,30,14,3,24,32)
  233.       return         
  234.  
  235.      Screen5:
  236.       a="It is a small step from drawing arcs to producing segments of",
  237.        "\a circle by adding the chords.  Those segments can be filled",
  238.        "\in a variety of ways."
  239.       call WindowText(W,a)
  240.       call Segment(300,90,50,25,32,1,0,11)
  241.       call APen(4) ; call Flood(W,1,330,80)
  242.       call Segment(300,90,50,25,32,1,11,21)
  243.       call APen(6) ; call Flood(W,1,300,110)
  244.       call Segment(300,90,50,25,32,1,21,32)
  245.       call APen(5) ; call Flood(W,1,260,80)
  246.       call APen(2) ; call Flood(W,1,300,90)
  247.         
  248.       do j = 150 to 450 by 150
  249.        call FillSegment(j,190,100,50,20,13,27,5,256+6,0)
  250.        call Segment(j,190,100,50,20,9,27,5,4,0)
  251.        call Segment(j+2,189,100,50,20,15,27,5,4,0)
  252.        k=j-86
  253.        do p = 1 to 6
  254.         call APen(8+p) ; call RectFill(W,k+p*2,160,k+p*2+2,180) ; end
  255.        end
  256.        k=520
  257.        do p = 1 to 6
  258.         call APen(8+p) ; call RectFill(W,k+p*2,160,k+p*2+2,180)
  259.        end
  260.       return
  261.   
  262.      Screen6:
  263.       a="\From arcs, chords, and sectors, we move on to segments as used in",
  264.        "\a pie chart.",
  265.        "\\If you watch it closely, you'll see that I cheat a bit, overlapping",
  266.        "\the segments slightly as they are drawn, to give a tidier appearance",
  267.        "\to the shared radii."
  268.        call WindowText(W,a)
  269.        s.1=2;e.1=6 ; s.2=5;e.2=15 ; s.3=14;e.3=20
  270.        s.4=19;e.4=23 ; s.5=22;e.5=28 ; s.6=27;e.6=3
  271.       do se = 1 to 6
  272.        call FillSegment(250,140,100,50,32,3,s.se,e.se,2048+256+5+se,1)
  273.        end
  274.       do i = 1 to 2  
  275.        call APen(i+(i>1)) ; call DrawEllipse(W,250,140,100+2*i,50+i)
  276.        end
  277.        return
  278.        
  279.     Screen7:      
  280.      a="Now let's boldly try our hand at something three-dimensional.",
  281.        "\We had some small pillars supporting a bridge on another screen.",
  282.        "\Here is something more ambitious. The foot of each pillar and of",
  283.        "\the cone are the interesting bits."
  284.      call WindowText(W,a)
  285.      call APen(13) ; call Move(W,60,172) ; call Draw(W,70,160)
  286.      call Draw(W,465,160) ; call Draw(W,475,172) ; call Draw(W,60,172)
  287.      call Flood(W,1,80,170) ; call APen(9) ; call RectFill(W,60,172,475,186)
  288.      do pi = 1 to 4 ; call Pillar(pi*100,70,100,24+6*pi,(pi=4)) ; end
  289.      return  
  290.      
  291.     Screen8:
  292.      a="\\   This attempt at globes with a 3D appearance is not all that",
  293.        "\   convincing, but at least it is reasonably fast."
  294.      call WindowText(W,a)
  295.      call Globe(220,140,50,25)
  296.      call Globe(320,200,60,30)
  297.      return         
  298.      
  299.     Screen9:      
  300.      a="    We'd better just check that the main functions used in this",
  301.       "\   program perform as required for ellipses as well as for circles."
  302.      call WindowText(W,a)
  303.      call Polygon(100,70,60,20,18,1,0) ; call Spokes(100,150,60,40,12,4,1)
  304.      call Fill(300,130,30,40,12,1,2048+6);call Arc(300,144,120,100,18,2,2,26)
  305.      call Segment(490,90,84,28,24,7,29,11)
  306.      call FillSegment(490,170,40,30,16,4,2,25,2048+256+6,0)
  307.      call Globe(300,206,60,10)
  308.      return
  309.      
  310.     Screen10:
  311.      a="The following circle-related functions can be found in the program.",
  312.       "\Some parts of the code are frequently duplicated to facilitate the",
  313.       "\lifting out of any functions you may wish to use elsewhere.",
  314.       "\\  Polygon(x,y,r1,r2,sides,pen)",
  315.       "\\  Spokes(x,y,r1,r2,sides,pen,rimflag)",
  316.       "\\  Fill(x,y,r1,r2,sides,pen+flags)",
  317.       "\     flags : 256 -> pattern ; 512 -> dither ; 2048 -> outlined",
  318.       "\\  Arc(x,y,r1,r2,sides,pen,start,finish)",
  319.       "\\  Segment(x,y,r1,r2,sides,pen,start,finish)",
  320.       "\     ArcBit:  Called by 'Arc' and 'Segment'",
  321.       "\\  FillSegment(x,y,r1,r2,sides,drawpen,start,finish,fillpen,flag)",
  322.       "\     flag = 'segment or sector'",
  323.       "\     FillSegBit:  Called by 'FillSegment'",
  324.       "\\  Pillar(left,top,height,width)",
  325.       "\\  Globe(x,y,r1,r2)"
  326.      call WindowText(W,a) ; call box(20,50,550,230,7)
  327.      return
  328.   
  329.      /* ----- Special polygons : pattern, spoked, alternate ----- */
  330.      
  331.     Polygon:
  332.      x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
  333.      call APen(arg(6)) ; call Move(W,x,y-r2) ; f = 1 ; step = twoPI/sides
  334.      do i =  -1.6 to 4.8 by step
  335.        co=x+r1*cos(i) ; si=y+r2*sin(i) 
  336.        if arg(7) = 1 then do ; f = ~f ; call APen(arg(6)+f) ; end
  337.        call Draw(W,co,si)
  338.        end   
  339.      return
  340.     
  341.     Spokes:
  342.      x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
  343.      call APen(arg(6)) ; call Move(W,x,y-r2) ; step = twoPI/sides
  344.      do i =  -1.6 to 4.8 by step
  345.        co=x+r1*cos(i) ; si=y+r2*sin(i) 
  346.        if arg(7) = 1 then call Draw(W,co,si) ; else call Move(W,co,si)
  347.        call Draw(W,x,y) ; call Draw(W,co,si)
  348.        end   
  349.      return
  350.     
  351.     Fill:
  352.      x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
  353.      call APen(arg(6)) ; call Move(W,x,y-r2) ; call AreaDraw(W,x,y-r2) 
  354.      step = twoPI/sides
  355.      do i =  -1.6 to 4.8 by step
  356.        co=x+r1*cos(i) ; si=y+r2*sin(i) 
  357.        call Draw(W,co,si) ; call AreaDraw(W,co,si)
  358.        end
  359.      call AreaEnd(W,arg(7))   
  360.      return
  361.  
  362.       /*  ------------  Shapes and Pieces  -----------  */
  363.          
  364.     Arc:
  365.      x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
  366.      call APen(arg(6)) ; st = arg(7) ; f = arg(8)
  367.      if st > f then do ; call ArcBit(st,32) ; call ArcBit(0,f) ; end
  368.      else call ArcBit(st,f)
  369.      return
  370.      
  371.     ArcBit:                    /* Called by 'Arc' and 'Segment' */
  372.      step = twoPI/sides 
  373.      start = (arg(1) - 8)*0.2 ; fin = (arg(2) - 8)*0.2
  374.      call Move(W,x+r1*cos(start),y+r2*sin(start)) 
  375.      do i =  start to fin by step
  376.        co=x+r1*cos(i) ; si=y+r2*sin(i) ; call Draw(W,co,si)
  377.        end   
  378.      return
  379.      
  380.     Segment:
  381.      x=arg(1) ; y=arg(2) ; r1=arg(3) ; r2=arg(4) ; sides=arg(5)
  382.      call APen(arg(6)) ; st = arg(7) ; f = arg(8)
  383.      if st > f then do 
  384.       call ArcBit(st,32) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
  385.       call ArcBit(0,f) 
  386.       end
  387.      else do ;
  388.       call ArcBit(st,f) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
  389.       end
  390.      call Draw(W,dx,dy)
  391.      return
  392.      
  393.     FillSegBit:                /* Called by 'FillSegment' */
  394.      start = (arg(1) - 8)*0.2 ; fin = (arg(2) - 8)*0.2
  395.      dx = x+r1*cos(start) ; dy = y+r2*sin(start)
  396.      call Move(W,dx,dy) ; call AreaDraw(W,dx,dy) ; step = twoPI/sides
  397.      do i =  start to fin by step
  398.        co=x+r1*cos(i) ; si=y+r2*sin(i) 
  399.        call Draw(W,co,si) ; call AreaDraw(W,co,si)
  400.        end   
  401.      return
  402.      
  403.     FillSegment:
  404.      x=arg(1) ; y=arg(2) ; r1=arg(3) ; r2=arg(4) ; sides=arg(5)
  405.      call APen(arg(6)) ; st = arg(7) ; f = arg(8) ; patt = arg(9)
  406.      SegOrSec = arg(10)
  407.      if st > f then do 
  408.       call FillSegBit(st,32) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
  409.       call FillSegBit(0,f) 
  410.       end
  411.      else do ;
  412.       call FillSegBit(st,f) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
  413.       end
  414.      if SegOrSec then do ; call Draw(W,x,y) ; call AreaDraw(W,x,y) ; end
  415.      call Draw(W,dx,dy) ; call AreaEnd(W,patt)
  416.      return
  417.      
  418.     Pillar:
  419.      left = arg(1) ; top = arg(2) ; height = arg(3) ; width = arg(4)
  420.      cylinder = (arg(5) = 0) ; step = width%8
  421.      if cylinder then do p = 0 to 7
  422.        call APen(p+8) 
  423.        call RectFill(W,left+p*step,top,left+p*step+step,top+height)
  424.       end
  425.      else do p = 0 to 7
  426.        call APen(p+8) ; call AreaDraw(W,left+width%2,top)
  427.        call AreaDraw(W,left+p*step,top+height)
  428.        call AreaDraw(W,left+p*step+step,top+height) ; call AreaEnd(W,p+8)
  429.       end
  430.       x=left+width/2 ; y = top+height-width%8 ; r1=width%2 ; r2=width%8
  431.       call APen(13)
  432.       step = twoPI/32 ; call Move(W,x+r1,y+r2) ; call AreaDraw(W,x+r1,y+r2) 
  433.       do i =  0 to 3.2 by step
  434.         co=x+r1*cos(i) ; si=y+r2*sin(i) 
  435.         call Draw(W,co,si) ; call AreaDraw(W,co,si)
  436.         end 
  437.       call Draw(W,x-r1,y+r2) ; call AreaDraw(W,x-r1,y+r2) 
  438.       call Draw(W,x+r1,y+r2) ; call AreaDraw(W,x+r1,y+r2) 
  439.       call AreaEnd(W,13)
  440.       return
  441.  
  442.      Globe:
  443.       x=arg(1) ; y = arg(2) ; r1 = arg(3) ; r2 = arg(4)
  444.       call AreaEllipse(W,x,y,r1,r2) ; call AreaEnd(W,8) 
  445.       drx = r1%16 ; dry = r2%16
  446.       do i = 1 to 7
  447.        call AreaEllipse(W,x+i*drx,y-i*dry,r1-i*drx*2,r2-i-i*dry*2) 
  448.        call AreaEnd(W,8+i)
  449.        end    
  450.       return
  451.      
  452.     
  453.      /* Hamilton, New Zealand March, 1995 */
  454.